|
PrepareMemoryForIO
and Execution Levels (08-June-98)Q I'm writing a native driver (a SCSI SIM)
that controls DMA hardware and needs to use partial preparation. How
can I do this without breaking the rules described in Table 9-2 of
"Designing PCI Cards and Drivers for Power Macintosh Computers"?
A The short answer is that you can't do this
without breaking the rules, but it's OK to break the rules in this
case. A native SCSI SIM on the traditional Mac OS must call
PrepareMemoryForIO
at native hardware-interrupt level,
and it is safe to do so. This is obviously going to require some
explanation. Hold on to your hats!
For background information on the problem, you should read the article The New Device Drivers: Memory Matters (develop 24). This article describes the official algorithm for implementing partial preparation mechanism in the native driver model. However, there are two problems with this algorithm:
So the algorithm described in
The
New Device Drivers: Memory Matters is not valid for SCSI SIMs on
the traditional Mac OS. There is, however, a relatively simple
workaround that does work in these circumstances. In the algorithm
described after Figure 2 of the develop
article, you can compress steps 2, 3 and 4 into one step,
eliminating the use of secondary-interrupt and software-interrupt
level execution. As a result, your SIM calls
PrepareMemoryForIO
at native hardware-interrupt time.
This is explicitly outlawed in Table 9-2 of "Designing PCI Cards and
Drivers for Power Macintosh Computers," but is the only way that
works.
The rest of this Q&A is a justification of why this works. To understand this discussion, you may need to reference Technote 1094: Virtual Memory Application Compatibility, which contains a comprehensive explanation of how virtual memory works on the traditional Mac OS.
On the traditional Mac OS, PrepareMemoryForIO
is
actually implemented as a wrapper around standard Virtual Memory
Manager routines. The specific routines of interest are
LockMemory
and GetPhysical
. The
implementation of PrepareMemoryForIO
is, in itself,
interrupt-safe; thus, calling PrepareMemoryForIO
is
allowed at any time calling the underlying Virtual Memory
Manager routines is allowed.
Note: On Mac OS 8.5 or higher, |
Technote
1104: Interrupt Safe Routines describes the interrupt-safe nature
of GetPhysical
and LockMemory
. To summarize
the discussion in that Technote, GetPhysical
is always
interrupt-safe and LockMemory
is interrupt-safe if
either a) paging is safe, or b) you can guarantee that locking the
memory will not cause any page faults.
In the case of a SCSI SIM, the traditional Mac OS guarantees that any transfer buffer passed to the SIM is held resident in memory. This guarantee is maintained by two mechanisms:
So, as the author of a SCSI SIM, you are guaranteed that transfer
buffers passed to your SIM are held resident. This implies that it's
always safe to call LockMemory
on those transfer
buffers, even at hardware-interrupt time. This, in turn, implies that
it is always safe to prepare those transfer buffers using
PrepareMemoryForIO
, even at hardware-interrupt time.
QED
-- Quinn "The Eskimo!"
Worldwide Developer Technical Support
Technical Q&As
Previous Question |
Contents | Next Question
To contact us, please use the
Contact Us page.